﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using XcoAppSpaces.Core;
using Microsoft.Ccr.Core;
using System.Threading;
using NUnit.Framework;
using XcoAppSpaces.Serialization.Json;
using XcoAppSpaces.Contracts.Exceptions;
using XcoAppSpaces.Transport.Sockets;

namespace test.XcoAppSpaces.Core
{
	[TestFixture]
	public class testLargePortSet
	{
		[Serializable] class MsgType1 { }
		[Serializable] class MsgType2 { }
		[Serializable] class MsgType3 { }
		[Serializable] class MsgType4 { }
		[Serializable] class MsgType5 { }
		[Serializable] class MsgType6 { }
		[Serializable] class MsgType7 { }
		[Serializable] class MsgType8 { }
		[Serializable] class MsgType9 { }
		[Serializable] class MsgType10 { }
		[Serializable] class MsgType11 { }
		[Serializable] class MsgType12 { }
		[Serializable] class MsgType13 { }
		[Serializable] class MsgType14 { }
		[Serializable] class MsgType15 { }
		[Serializable] class MsgType16 { }
		[Serializable] class MsgType17 { }
		[Serializable] class MsgType18 { }
		[Serializable] class MsgType19 { }
		[Serializable] class MsgType20 { }
		[Serializable] class MsgType21 { }
		class LargeWorkerContract : PortSet
		{
			public LargeWorkerContract()
				: base(typeof(MsgType1), typeof(MsgType2), typeof(MsgType3), typeof(MsgType4), typeof(MsgType5),
				typeof(MsgType6), typeof(MsgType7), typeof(MsgType8), typeof(MsgType9), typeof(MsgType10),
				typeof(MsgType11), typeof(MsgType12), typeof(MsgType13), typeof(MsgType14), typeof(MsgType15),
				typeof(MsgType16), typeof(MsgType17), typeof(MsgType18), typeof(MsgType19), typeof(MsgType20),
				typeof(MsgType21))
			{ }
		}

		class LargeWorkerImpl : LargeWorkerContract
		{
			public MsgType21 Data;

			[XcoConcurrent]
			void Process(MsgType21 data)
			{
				this.Data = data;
			}
		}

		[Test]
		public void TestRunWorkerWithVeryLargePortSet()
		{
			using (XcoAppSpace space1 = new XcoAppSpace("tcp.port=8000"),
				space2 = new XcoAppSpace("tcp.port=8001"))
			{
				var worker = new LargeWorkerImpl();
				space1.RunWorker<LargeWorkerContract>(worker);

				var remotePort = space2.ConnectWorker<LargeWorkerContract>(Environment.MachineName + ":8000");
				
				Assert.IsNull(worker.Data);
				remotePort.PostUnknownType(new MsgType21());

				Thread.Sleep(1000);
				Assert.IsNotNull(worker.Data);
			}
		}
	}
}
